home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / WEDITS22.ARJ / WEKBD.PAS < prev    next >
Pascal/Delphi Source File  |  1991-08-13  |  5KB  |  230 lines

  1. UNIT WEKbd;
  2. { -- This is the Low Level Keyboard Module for WWIVEdit 2.2
  3.   -- Last Modified : 8/13/91
  4.   -- Written By:
  5.   --   Adam Caldwell
  6.   --
  7.   -- This Code is Limited Public Domain (see WWIVEDIT.PAS for details)
  8.   --
  9.   -- Purpose : Provides low level, buffered keyboard input routines
  10.   --
  11.   -- Know Errors: Will lock up a computer if the user hangs up while
  12.   --  seperate_local_input is on.  This only occurs during chat mode.
  13.   --
  14.   -- Planned Enhancements : Implementing fix described in WECHAT.PAS
  15.   --
  16.   -- }
  17. {$R-,V-,S-,B-,E-,N-}   { These Optomize things as much as possible }
  18.  
  19. INTERFACE
  20.  
  21. VAR
  22.   TrueKeyboard : BOOLEAN;       { True if ANY key is pressed on the local keyboard }
  23.  
  24.  
  25. PROCEDURE Drain;
  26. FUNCTION  ReadKey:char;
  27. FUNCTION  KeyPressed:boolean;
  28. FUNCTION  Empty:boolean;
  29. PROCEDURE SeperateLocalInput;
  30. PROCEDURE MergeLocalInput;
  31. FUNCTION  KeyPressedL:boolean;
  32. FUNCTION  ReadKeyL:char;
  33. PROCEDURE StuffIn(s:string);
  34.  
  35. IMPLEMENTATION
  36.  
  37. USES DOS,WEVars;
  38.  
  39. CONST
  40.   BufferSize = 1024;
  41.  
  42. TYPE
  43.   KeyBuffer = RECORD
  44.       Buffer : ARRAY[0..Buffersize-1] OF char;
  45.       head : integer;
  46.       tail : integer;
  47.   END;
  48.  
  49. VAR
  50.   LKeyBuffer : KeyBuffer;  { Local Key Buffer - when active }
  51.   RKeyBuffer : KeyBuffer;  { Remote Key Buffer }
  52.   KbdHead : WORD ABSOLUTE $40:$1a;
  53.   KbdTail : WORD ABSOLUTE $40:$1c;
  54.   KbdMin : WORD ABSOLUTE $40:$80;
  55.   KbdMax : WORD ABSOLUTE $40:$82;
  56.   OldDos    : pointer;
  57.   installedInt9 :boolean;
  58.   OldInt9 : pointer;
  59.   InDos : boolean;
  60.  
  61.  
  62.  
  63. PROCEDURE Enque(VAR b:KeyBuffer; ch:char);
  64. BEGIN
  65.   WITH B DO BEGIN
  66.     buffer[tail]:=ch;
  67.     tail:=(tail+1) MOD BufferSize;
  68.   END
  69. END;
  70.  
  71. FUNCTION DosEmptyKeyBuffer : boolean;
  72. VAR
  73.   empty:boolean;
  74.   r : registers;
  75. BEGIN
  76.   IF KbdHead<>KbdTail THEN TrueKeyboard:=TRUE;
  77.   r.ah:=$06;
  78.   r.dl:=$FF;
  79.   msdos(r);
  80.   Empty:=(r.flags AND FZero) >0;
  81.   IF not Empty THEN Enque(RKeyBuffer,chr(r.al));
  82.   DosEmptyKeyBuffer := Empty;
  83. END;
  84.  
  85. PROCEDURE Drain;
  86. BEGIN
  87.   WHILE NOT DosEmptyKeyBuffer DO ;
  88. END;
  89.  
  90. FUNCTION EmptyBuffer(VAR B:KeyBuffer):boolean;
  91. BEGIN
  92.   EmptyBuffer:=b.head=b.tail
  93. END;
  94.  
  95.  
  96.  
  97. FUNCTION DeQue(VAR b:KeyBuffer):char;
  98. BEGIN
  99.   WITH B DO BEGIN
  100.     DeQue:=buffer[head];
  101.     head:=(head+1) MOD BufferSize
  102.   END
  103. END;
  104.  
  105.  
  106. FUNCTION KeyPressedL:boolean;
  107. BEGIN
  108.   KeyPressedL:=NOT EmptyBuffer(LKeyBuffer)
  109. END;
  110.  
  111. FUNCTION ReadKeyL:char;
  112. BEGIN
  113.   REPEAT UNTIL KeyPressedL;
  114.   ReadKeyL:=DeQue(LKeyBuffer);
  115. END;
  116.  
  117. PROCEDURE NewInt9;
  118. INTERRUPT;
  119. BEGIN
  120.   inline( $9C/ $FF/ $1E/ OldInt9 ); { Pushf / Call Far [OldInt9] }
  121.   IF KbdHead<>KbdTail THEN
  122.   BEGIN
  123.     WITH LKeyBuffer DO BEGIN
  124.       buffer[tail]:=chr(Mem[$40:KbdHead]);
  125.       tail:=(tail+1) MOD BufferSize;
  126.     END;
  127.     IF Mem[$40:KbdHead]=0 THEN
  128.     WITH LKeyBuffer DO BEGIN
  129.       buffer[tail]:=chr(Mem[$40:KbdHead+1]);
  130.       tail:=(tail+1) MOD BufferSize;
  131.     END;
  132.     KbdHead:=KbdHead+2;
  133.     IF KbdHead=KbdMax THEN KbdHead:=KbdMin;
  134.   END;
  135. END;
  136.  
  137. PROCEDURE MergeLocalInput;
  138. BEGIN
  139.   IF InstalledInt9 THEN
  140.   BEGIN
  141.     SetIntVec(9,OldInt9);
  142.     InstalledInt9:=FALSE;
  143.   END;
  144. END;
  145.  
  146.  
  147. PROCEDURE SeperateLocalInput;
  148. BEGIN
  149.   IF NOT InstalledInt9 THEN
  150.   BEGIN
  151.     GetIntVec(9,OldInt9);
  152.     SetIntVec(9,@NewInt9);
  153.     InstalledInt9:=TRUE;
  154.     LKeyBuffer.Head:=LKeyBuffer.Tail;
  155.     RKeyBuffer.Head:=RKeyBuffer.Tail;
  156.   END;
  157. END;
  158.  
  159. FUNCTION empty : boolean;
  160. BEGIN
  161.   empty  :=  DosEmptyKeyBuffer AND EmptyBuffer(RKeyBuffer);
  162. END;
  163.  
  164.  
  165. FUNCTION KeyPressed : boolean;
  166. BEGIN
  167.   IF KbdHead<>KbdTail THEN TrueKeyboard:=TRUE;
  168.   keypressed  :=  not empty
  169. END;
  170.  
  171. PROCEDURE StuffIn(s:string);
  172. VAR i:integer;
  173. BEGIN
  174.   FOR i:=1 TO length(s) DO
  175.     Enque(RKeyBuffer,s[i]);
  176. END;
  177.  
  178. PROCEDURE WriteKeyBuffer(ch:char);
  179. VAR
  180.   r:registers;
  181. BEGIN
  182.   IF KeyBIOS THEN BEGIN
  183.     r.ah:=5; r.cl:=ord(ch);
  184.     intr($16,r);
  185.   END
  186.   ELSE BEGIN
  187.     Mem[$40:KbdTail]:=ord(ch);
  188.     Mem[$40:KbdTail+1]:=0;
  189.     KbdTail:=KbdTail+2;
  190.     IF KbdTail=KbdMax THEN KbdTail:=KbdMin;
  191.   END;
  192. END;
  193.  
  194. FUNCTION Macro(ch:char):char;
  195. VAR r:registers;
  196. BEGIN
  197.   WriteKeyBuffer(^P);
  198.   WriteKeyBuffer(ch);
  199.   r.ah  :=  $07;  msdos(r);
  200.   Macro:=chr(r.al);
  201. END;
  202.  
  203. FUNCTION ReadKey : char;
  204. VAR
  205.   ch : char;
  206.   r : registers;
  207. BEGIN
  208.   IF KbdHead<>KbdTail THEN TrueKeyboard:=TRUE;
  209.   REPEAT
  210.     IF EmptyBuffer(RKeyBuffer) THEN
  211.     BEGIN
  212.       r.ah  :=  $07;
  213.       msdos(r);
  214.       Enque(RKeyBuffer,chr(r.al));
  215.     END;
  216.     Ch:=Deque(RKeyBuffer);
  217.     IF (ch IN [^A,^D,^F]) AND (NOT InDos) THEN ch:=Macro(ch);
  218.   UNTIL NOT (ch IN [^A,^D,^F]);
  219.   ReadKey:=ch;
  220. END;
  221.  
  222. BEGIN
  223.   LKeyBuffer.Head:=0;
  224.   LKeyBuffer.Tail:=0;
  225.   RKeyBuffer.Head:=0;
  226.   RKeyBuffer.Tail:=0;
  227.   TrueKeyboard:=FALSE;
  228.   InstalledInt9:=FALSE;
  229.   InDos:=GetEnv('BBS')='';
  230. END.